<?php

namespace Syrius\Type;

/**
 * Enter description here ...
 * @package	Type
 * @abstract
 * @author	Domenico Biancardi <domenico.biancardi@gmail.com>
 * @link	http://code.google.com/p/syrius/
 *
 */ abstract class Type {
	protected $length = 255;

    /**
     * Formato della stringa della data utilizzata per convertire il valore
     * ricevuto dal database
     * @var string
     */
    protected $format = "d-m-Y";
	/**
	 * A custom get name function
	 */
	protected $_customGet;

	/**
	 * A custom set name function
	 */
	protected $_customSet;

	protected $default = NULL;

	protected $enum = array();

	protected $null = true;

	protected $serial = false;

	protected $primary = false;

	protected $index = false;

	protected $unique = false;

	protected $collate = "utf8_bin";

	protected $comment;

	protected $column_format;

	protected $storage;

	protected $fulltext;

	/**
	 * Get all the properties of the field
	 */
	public function getProperties() {
		return $this->_properties;
	}

	public function getAttribute($name) {
		if (isset ($this->$name))
			return $this->$name;
		return null;
	}

	public function setAttribute($name, $value) {
		$this->$name = $value;
	}

	public function __construct($opts) {
		foreach ($opts as $k => $v) {
			$this->setAttribute($k, $v);
		}
	}

	/**
	 * Generazione della rappresentazione sql
	 */
	public function __toString() {
		$str = $this->type . "(" . $this->length . ")";
		// column definition
		if ($this->serial) {
			$str .= " AUTO_INCREMENT";
		}
		if ($this->null) {
			$str .= " NULL";
		} else {
			$str .= " NOT NULL";
		}
		if ($this->default) {
			$str .= " DEFAULT " . $this->default;
		}
		if ($this->comment) {
			$str .= " COMMENT '" . $this->comment . "'";
		}
		if ($this->column_format) {
			$str .= " COLUMN_FORMAT " . $this->column_format;
		}
		if ($this->storage) {
			$str .= " STORAGE " . $this->storage;
		}

		// index
		if ($this->primary) {
		}
		if ($this->index) {
			$index = new Syrius_Keys_Index ("test");
			$str .= ", INDEX " . $index;
		}
		if ($this->unique) {
		}
		if ($this->fulltext) {
		}
		/*if ($this -> relation){
}*/

		return $str;
	}

	public function setSource($table) {
		$this->_source = $table;
	}

	protected $_table;

	public function validate($input) {
		// se vengono passati tutti i controlli senza exception il dato è corretto
		$this->nullControl($input);
        if ($this -> length)
            new \Syrius\Validator\MaxLengthValidator($input, $this -> length, "Superata lunghezza massima {len} per il valore {value}");
        
		//$this->maxLengthControl($input);
		$this->minLengthControl($input);
		$this->uniqueControl($input);
		$this->enumControl($input);
		$inputDb = $this->_toDb($input);
		$this->typeControl($inputDb);
		return $inputDb;
	}

	/**
	 * Ritorna il valore che verrà inserito a database
	 */
	public function _toDb($input) {
		return $input;
	}

	protected $maxLength;

	protected $minLength;

	protected function nullControl($input) {
		if ($this->null === false && $input == "")
			throw new Syrius_Exception_Validation_Not_Null ();
	}

	protected function maxLengthControl($input) {
		if ($this->maxLength != "" && !($input < $this->maxLength))
			throw new Syrius_Exception_Validation_Max_Length ();
	}

	protected function uniqueControl($input) {
	}

	protected function enumControl($input) {
	}

	protected function typeControl($input) {
		if (gettype($input) != "string") {
			throw new \Syrius\Exception\Validation_Type ();
		}
	}

	protected function minLengthControl($input) {
		if ($this->maxLength != "" && !($input < $this->maxLength))
			throw new Syrius_Exception_Validation_Max_Length ();
	}

	/**
	 * Ritorna il valore che verrà inserito a database
	 */
	public function _fromDb($input) {
		return $input;
	}

	/**
	 * nome del campo
	 */
	protected $name;

	/**
	 * Funzione che permette di togliere tutte le chiavi da un field, la funzione viene utilizzata quando si effettua un update table
	 */
	public function removeKeys() {
		$this->index = false;
	}

	public function isIndex() {
		if ($this->index)
			return true;
		if ($this->primary)
			return true;
		return false;
	}

	public function getName() {
		return $this->name;
	}

}

?>
